gusucode.com > VC++ 三维图形绘制实例-源码程序 > VC++ 三维图形绘制实例/code/eidterView.cpp

    // eidterView.cpp : implementation of the CEidterView class
// Download by http://www.NewXing.com
#include "stdafx.h"
#include "eidter.h"

#include "eidterDoc.h"
#include "eidterView.h"
#include <math.h>
#define rad 3.14159265/180.0

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CEidterView

IMPLEMENT_DYNCREATE(CEidterView, CView)

BEGIN_MESSAGE_MAP(CEidterView, CView)
	//{{AFX_MSG_MAP(CEidterView)
	ON_UPDATE_COMMAND_UI(ID_DISPLAY, OnUpdateDisplay)
	ON_COMMAND(ID_DISPLAY, OnDisplay)
	ON_COMMAND(ID_DRAW_XX, OnDrawXx)
	ON_COMMAND(ID_SINSITA, OnSinsita)
	ON_COMMAND(ID_SIN5_SITA, OnSin5Sita)
	ON_COMMAND(ID_DISPLAY2, OnDisplay2)
	ON_COMMAND(ID_3D_NOT_HIDE, On3dNotHide)
	
	ON_COMMAND(ID_BALL_WWW, OnBallWww)
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CEidterView construction/destruction

CEidterView::CEidterView()
{
	// TODO: add construction code here

}

CEidterView::~CEidterView()
{
}

BOOL CEidterView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CEidterView drawing
bool first=true;

void CEidterView::OnDraw(CDC* pDC)
{
	CEidterDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if(first){
	 GetParentFrame( )->ShowWindow(SW_SHOWMAXIMIZED);
	 first=false;
	}

	// TODO: add draw code for native data here
}

/////////////////////////////////////////////////////////////////////////////
// CEidterView printing

BOOL CEidterView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CEidterView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CEidterView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CEidterView diagnostics

#ifdef _DEBUG
void CEidterView::AssertValid() const
{
	CView::AssertValid();
}

void CEidterView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CEidterDoc* CEidterView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CEidterDoc)));
	return (CEidterDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CEidterView message handlers

//////////////
float func(float x)
{
	return x*x;
}
//////////////////
void CEidterView::OnUpdateDisplay(CCmdUI* pCmdUI) 
{
	
}

int out_float(float xx,char*outstring)
{
	int i;
	int len;

	i=log10(xx);
	xx=xx*pow(10,-i);
		if(i==0){
		sprintf(outstring,"%f",xx);
		len=strlen(outstring);
		outstring[len-4]='\0';
	}else{
		///sprintf(outstring,"%fe%d",xx,i);
			sprintf(outstring,"%f",xx);
			len=strlen(outstring);
			outstring[len-4]='\0';
			sprintf(outstring,"%se%d",outstring,i);
	}
	
	return 1;
}


float glo_org_x=0.1,glo_org_y=-0.6,glo_org_z=-2.9;
float cx=1;

void CEidterView::OnDisplay() 
{
	float a=0,b=2,c=100;
	MyCDC dc(this);	
	dc.DrawChart(func,a,b,c);
}

//////////
float func2(float x)
{
	return(x*x*x+3*x*x+0.5);
}
///////////
void CEidterView::OnDrawXx() 
{
	float a=0,b=2,c=100;
	MyCDC dc(this);	
	dc.DrawChart(func2,a,b,c);
   	
}
float func3(float sita)
{
	return((float)sin(sita));
}

void CEidterView::OnSinsita() 
{
	
	MyCDC dc(this);	
	dc.DrawDirection(func3,200);
   	
}

float func4(float sita)
{
	return((float)sin(5*sita));
}

void CEidterView::OnSin5Sita() 
{
	MyCDC dc(this);	
	dc.DrawDirection(func4,200);
   	
}

float func0(float x)
{
	if(x>0)return((float)(2*x*x+x));
	return(x*x*x+3*x*x+0.5);
}
void CEidterView::OnDisplay2() 
{
	float a=-2,b=2,c=100;
	MyCDC dc(this);	
	dc.DrawChart(func0,a,b,c);
  	
}
float func3d1(float x,float y)
{
	return((float)(x*x+y*y));
}
float func3d2(float x,float y)
{
	return((float)sqrt(1.0-x*x+y*y));
}
void CEidterView::On3dNotHide() 
{
	MyCDC dc(this);	
	//dc.draw3d();
	glo_org_x=0.1,glo_org_y=-0.6,glo_org_z=-2.9;	

	dc.Draw3D(func3d1,0,1,0,1,0.5);
   	
}

void CEidterView::OnxADD() 
{
	glo_org_x+=0.5;
	MyCDC dc(this);
	dc.Draw3D(func3d2,-1,1,-1,1,cx);
	
}

void CEidterView::OnyAND() 
{
	glo_org_y+=0.5;
	MyCDC dc(this);
	dc.N1=100;
	dc.N2=100;
	dc.Draw3D(func3d2,-1,1,-1,1,cx);
	
	
}

void CEidterView::OnZAdd() 
{
	glo_org_z+=0.5;
	MyCDC dc(this);
	dc.N1=100;
	dc.N2=100;
	dc.Draw3D(func3d2,-1,1,-1,1,cx);
  	
}

void CEidterView::OnXSub() 
{
	glo_org_x-=0.3;
	MyCDC dc(this);
	dc.N1=100;
	dc.N2=100;
	dc.Draw3D(func3d2,-1,1,-1,1,cx);
	
}

void CEidterView::OnYSub() 
{
	glo_org_y-=0.3;
	MyCDC dc(this);
	dc.N1=100;
	dc.N2=100;
	dc.Draw3D(func3d2,-1,1,-1,1,cx);
	
}

void CEidterView::OnZSub() 
{
	glo_org_z-=0.3;
	MyCDC dc(this);
	dc.N1=100;
	dc.N2=100;
	dc.Draw3D(func3d2,-1,1,-1,1,cx);
	
}

void CEidterView::OnCAdd() 
{

cx+=0.5;
MyCDC dc(this);
dc.N1=100;
	dc.N2=100;
	dc.Draw3D(func3d2,-1,1,-1,1,cx);// TODO: Add your command handler code here
	
}

void CEidterView::OnCSub() 
{
	cx-=0.3;
MyCDC dc(this);
dc.N1=100;
	dc.N2=100;
	dc.Draw3D(func3d2,-1,1,-1,1,cx);// TODO: Add your command handler code here

  	
}

void CEidterView::OnHalfBall() 
{
	MyCDC dc(this);	
	dc.N1=100;
	dc.N2=100;
	//dc.draw3d();
	//glo_org_x=0.1,glo_org_y=-0.6,glo_org_z=-2.9;	

	dc.Draw3D(func3d2,-1,1,-1,1,cx);
   	
}


/*************************以下为MyCDC 类的实现******************/
void MyCDC::agoodball()
{
	int i,j;
  float x,y,z,r;
    glClearColor(0.5,0.6,0.7,1.0);
	glClear(GL_COLOR_BUFFER_BIT);
	glColor3f(1.0,1.0,1.0);
	glLoadIdentity();
	glTranslatef(0.0,0.0,-5.0);
	glRotatef(45.0,-45.0,0.0,1.0);
	glScalef(1.0,1.0,1.0);
	for(i=0;i<180;i+=5){
		glBegin(GL_LINE_LOOP);
		r=2.0*sin(i*rad);
		z=2.0*cos(i*rad);
		for(j=0;j<360;j+=5){
			x=r*cos(j*rad);
			y=r*sin(j*rad);
			glVertex3f(x,y,z);
		}
		glEnd();
	}
	for(j=0;j<360;j+=5){
		glBegin(GL_LINE_LOOP);
		for(i=0;i<=180;i+=5){
			r=2*sin(i*rad);
			z=2*cos(i*rad);
			x=r*cos(j*rad);y=r*sin(j*rad);
			glVertex3f(x,y,z);
		}
		glEnd();
	}
	glFlush();
	SwapBuffers(::GetDC(mywndp->GetSafeHwnd()));
 
}
BOOL MyCDC::SetupPixelFormat(HDC hDC)
{
	static PIXELFORMATDESCRIPTOR pfd={
		sizeof(PIXELFORMATDESCRIPTOR),1,
			PFD_DRAW_TO_WINDOW|
			PFD_SUPPORT_OPENGL|
			PFD_DOUBLEBUFFER,
			PFD_TYPE_RGBA,
			24,0,0,0,0,0,0,
			0,
			0,
			0,
			0,0,0,0,
			32,
			0,0,
			PFD_MAIN_PLANE,
			0,0,0,0
	};
	int pixelformat;
	if((pixelformat=ChoosePixelFormat(hDC,&pfd))==0){
		AfxMessageBox("choose pixelformate failed");
		return FALSE;
	}
		if(SetPixelFormat(hDC,pixelformat,&pfd)==FALSE){
			AfxMessageBox("Set Pixel Formate failed");
			return FALSE;
		}
		return TRUE;

/////
}
bool MyCDC::create_dc()
{
	HDC hDC;	
   HGLRC hRC;
   hDC=::GetDC(mywndp->GetSafeHwnd());
   SetupPixelFormat(hDC);
   hRC=wglCreateContext(hDC);
   wglMakeCurrent(hDC,hRC);

	return true;
}
bool MyCDC::init_h3d()
{
   glViewport(0,0,600,600);

   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   gluPerspective(45.0,(float)1.0,1.0,100.0);
/////this is the ortho projection
//glOrtho(-1.0,20,-3,3,0,20);
  glMatrixMode(GL_MODELVIEW);		
  return true;
}
void MyCDC::draw3d()
{
	create_dc();
	init_h3d();
	agoodball();
	///free_h3d();
}
bool MyCDC::free_h3d()
{
	HGLRC hRC;
	hRC=wglGetCurrentContext();
	wglMakeCurrent(NULL,NULL);
	if(hRC)wglDeleteContext(hRC);
	return true;
}
void MyCDC::DrawChart(float(*func)(float),float a,float b,float c)
{
	int x,y;
	float yx,xx;
	int i;
	char s[100];
       y=(int)(c*(func(a)));
	   y=300-y; //调整坐标
	   MoveTo(100,y);//建立映射起点100,300
       for(i=102;i<500;i=i+2){       //利用逆映射计算并绘图
           yx=a+ (i-100.0)*(b-a)/400.0;
	       y=(int)(c* func(yx) );
	       y=300-y;
	       LineTo(i,y);  //画函数图线
	 
	  }
	   MoveTo(100,10);
	   LineTo(100,600);
	   MoveTo(100,300);
	   LineTo(500,300);

	   ///////////
	   //////////////
	   ///纵坐标
	   for(i=-250;i<=250;i+=50){		   
		   xx=((float)i/(c));		   		   
		   out_float(xx,s);
           TextOut(40,300-i,s);//绘制坐标
	   }
	   ///////////横坐标
	   for(i=150;i<=500;i+=50){       //利用逆映射计算并绘图
           yx=a+ (i-100.0)*(b-a)/400.0;	       
		   out_float(yx,s);           
		   TextOut(i,310,s);		 
	  }
	   /////////

	   
	   
}
void MyCDC::DrawDirection(float(*func)(float),float c)
{
	float max=0.0;// max 为一变量记录最大指
	float r,s,x1,y1;
	int x,y,i,R;
	char ss[100];
   r=c*(func(0));
   if(max<r)max=r;
   x=int(fabs(r));
   y=0;
   x=300+x;
   y=300-y;
  MoveTo(x,y);
  //从0度画到360度
  for(i=1;i<360;i++){
       s=(float)i*3.1416/180.0;
	   r=c*(func(s));r=fabs(r);
	   if(max<r)max=r;
	   x1=r*cos(s);y1=r*sin(s);
	   x=(int)x1;y=(int)y1;
	   x=300+x;
       y=300-y;
	   LineTo(x,y);
  }
  r=max/4;s=0;
//画出坐标的分度
  for(i=1;i<=4;i++){
	  s=s+r;
	  R=(int)s;
      Arc(300-R,300-R,300+R,300+R,300+R,300,300-1+R,300+1);
  }
  MoveTo(10,300);
	   LineTo(600,300);
	   MoveTo(300,10);
	   LineTo(300,650);
	   ///////////横坐标
	   float yx;
	   s=0;
	   for(i=1;i<=4;i++){
	     s=s+r;
	     R=(int)s;         
		  yx=float((i)/(4.0));	       
		   out_float(yx,ss);           
		   TextOut( R+300,310,ss);	
  }
	  

}
void MyCDC::Draw3D(float(*func)(float,float),float a1,float b1, float a2,float b2,float c)
{
	create_dc();
	init_h3d();
	glClearColor(0.5,0.6,0.7,1.0);
	glClear(GL_COLOR_BUFFER_BIT);
	glColor3f(1.0,1.0,1.0);
	///glLoadIdentity();
	glTranslatef(glo_org_x,glo_org_y,glo_org_z);
	glRotatef(-45.0,0.0,0.1,0.0);
	glScalef(1.0,1.0,1.0);
/////////
	 
   
	////////
	   glBegin(GL_LINE_STRIP);
			glVertex3f(0,0,0);
			glVertex3f(2,0,0);		
		glEnd();
		
		
		glBegin(GL_LINE_STRIP);
			glVertex3f(0,0,0);
			glVertex3f(0,2,0);		
		glEnd();
		
		glBegin(GL_LINE_STRIP);
			glVertex3f(0,0,0);
			glVertex3f(0,0,2);
		glEnd();
		
		/**/
	
	int i,j,k;
	float x,y,z;
	for(i=0;i<=N1;i++){ //利用逆映射计算并绘图
		glBegin(GL_LINE_STRIP);
		for(j=0;j<=N2;j++){
			x=(GLfloat)( i/(N1*1.0)*(b1-a1));
			z=(GLfloat)( j/(N2*1.0)*(b2-a2));
            y=(GLfloat)(c*func(x,y));
			glVertex3f(x,y,z);
		}
		glEnd();
	}

	for(j=0;j<=N2;j++){
		glBegin(GL_LINE_STRIP);
		for(i=0;i<=N1;i++){
			x=(GLfloat)( i/(N1*1.0)*(b1-a1));
			z=(GLfloat)( j/(N2*1.0)*(b2-a2));
            y=(GLfloat)(c*func(x,y));              
			glVertex3f(x,y,z);
		}
		glEnd();
	} 
/**/
	glFlush();
	SwapBuffers(::GetDC(mywndp->GetSafeHwnd()));

}


void CEidterView::OnBallWww() 
{
   	MyCDC dc(this);	
	dc.draw3d();
}